package parsetree;

import gui.text.MathDocument;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;


public abstract class AbstractElement implements Element {
    
    private ParseTree parseTree;
    private BranchElement parent;
    protected SimpleAttributeSet attributes;
    
    public AbstractElement(ParseTree parseTree, BranchElement parent)
    {
        this(parseTree, parent, new SimpleAttributeSet());
    }
    
    public AbstractElement(ParseTree parseTree, BranchElement parent, AttributeSet attributes)
    {
        this.parseTree = parseTree;
        this.parent = parent;
        this.attributes = new SimpleAttributeSet(attributes);
        if(parent != null) {
            this.attributes.setResolveParent(parent.getAttributes());
        }
    }
    
    @Override
    public AttributeSet getAttributes()
    {
        return attributes;
    }
    
    @Override
    public MathDocument getDocument()
    {
        return parseTree.getDocument();
    }
    
    @Override
    public BranchElement getParent()
    {
        return parent;
    }
    
    @Override
    public BranchElement getParentElement()
    {
        return getParent();
    }
    
    @Override
    public ParseTree getParseTree()
    {
        return parseTree;
    }
    
    @Override
    public void addAttributes(AttributeSet newAttributes)
    {
        attributes.addAttributes(newAttributes);
    }
    
    @Override
    public void setAttributes(AttributeSet replacementAttributes)
    {
        attributes.removeAttributes(attributes);
        attributes.addAttributes(replacementAttributes);
    }
    
    @Override
    public String toString()
    {
        return getName() + " [" + getStartOffset() + ", " + getEndOffset() + "]";
    }
    
    @Override
    public BranchElement setParent(AbstractBranchElement newParent)
    {
        BranchElement oldParent = parent;
        parent = newParent;
        return oldParent;
    }
    
    @Override
    public void writeExternal(ObjectOutput out) throws IOException
    {
        out.writeObject(parseTree);
        out.writeObject(parent);
        out.writeObject(attributes);
    }
    
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
    {
        parseTree = (ParseTree) in.readObject();
        parent = (BranchElement) in.readObject();
        attributes = (SimpleAttributeSet) in.readObject();
    }
}